package com.xb.loan.util.dom4j;


import com.xb.loan.util.ObjectHelper;
import com.xb.loan.util.OgnlHelper;
import com.xb.loan.util.file.FileLoader;
import com.xb.loan.util.log.DefaultLoggerFacotry;
import org.dom4j.*;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.slf4j.Logger;

import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.*;


/**
 * XML的帮助类，
 * @author heipn
 * @version 1.01
 */
public class Dom4jHelper {
    
	private static Logger logger = DefaultLoggerFacotry.getLogger(Dom4jHelper.class);
     /**
      * 获取Document
      * @param in
      * @return
      * @throws Exception
      */
	 public static Document getDocument(InputStream in) throws Exception {

	        SAXReader reader = new SAXReader();
     
	        return reader.read(in);
	        
	 }
	 
	 /**
	  * 通过String获取Document
	  * @param msg
	  * @return
	 * @throws  
	  * @throws Exception
	  */
	 public static Document getDocument(String msg){
		    Document doc = null;
		    if(msg != null){
		    	try {
					doc = DocumentHelper.parseText(msg);
				} catch (DocumentException e) {
					e.printStackTrace();
					logger.error(e.getMessage());
				}
		    }
		    return doc;
	 }
	/**
	 * 获取XML流的root节点
	 * @param in
	 * @return
	 */
	public static Element getRootElement(InputStream in)throws Exception{
		
		SAXReader reader = new SAXReader();
		Element root = null;
	    Document doc = reader.read(in);
		root = doc.getRootElement();
	    
		return root;
	}
	
	
	
	
	/**
	 * 获取XML字符串的root节点
	 * @param xmlContent
	 * @return
	 * @throws Exception
	 */
	public static Element getRootElement(String xmlContent)throws Exception{
		StringReader strReader = new StringReader(xmlContent);
		SAXReader reader = new SAXReader();
		Element root = null;
	    Document doc = reader.read(strReader);
		root = doc.getRootElement();
	    
		return root;
	}
    
    /**
     * 在节点中获取格式为
     * <name>value</name>子节点的节点名称和值，并作为map的key和value放入map中返回。
     * @param node
     * @return
     */
	public static Map<String,String> childeNodeMapping(Node node){
	    return nodeMapping(node,"*");
	}
	
	/**
	 * 获取某个节点的所有属性，并将属性的名称和值以key-value的形式放入map中返回。
	 * @param node
	 * @return
	 */
	public static Map<String,String> nodeProperitesMapping(Node node){
		return nodeMapping(node,"/@*");
	}
   /**
    * 获取节点的子节点的名称
    * @param node
    * @param expression
    * @return
    */ 
	@SuppressWarnings("unchecked")
	public static List<Node> nodeList(Node node,String expression){
		List<Node> childNodes = node.selectNodes(expression);		
		return childNodes;
	}
	@SuppressWarnings("unchecked")
	private static Map<String,String> nodeMapping(Node node,String expression){
		 //获取所有该节点下的所有节点
		List<Node> childNodes = node.selectNodes(expression);
	    
		Map<String,String>  map = new HashMap<String,String>();
	    
		if(childNodes != null && childNodes.size() > 0){
		   for(Node childNode:childNodes){
			   String name = childNode.getName();
			   String value = childNode.getStringValue();
			   logger.debug("parser node get key and value,"+name+" = " +value);
			   map.put(name, value);
		   }
		}
		
		return map;
	}
	
	
	@SuppressWarnings("unchecked")
	public static List getNodes(Node n, String expression) {
        return n.selectNodes(expression);
    }
	
	
	
	@SuppressWarnings("unchecked")
	public static Properties getChildValues(Node n) {

        List<Node> childNodes = n.selectNodes("*");

        Properties pro = new Properties();

        if (childNodes != null) {
            for (Node cn : childNodes) {
                pro.put(cn.getName(), cn.getStringValue());
            }
        }
        return pro;

    }
	
	public static void main(String[] args)throws Exception{
//	  InputStream in =	FileLoader.getInputStream("H:\\palm-app\\palmutil\\resource\\bean.xml", FileLoader.TYPE_FILEPATH);
//	  Element root = getRootElement(in);
		Document doc = DocumentHelper.createDocument();
		Element root = doc.addElement("root");
		root.addElement("state").setText("0");
		root.addElement("down_time").setText("销售期未开始");
		StringWriter out = new StringWriter();
		OutputFormat format = OutputFormat.createCompactFormat();
		  format.setNewLineAfterDeclaration(false);
		  XMLWriter output = new XMLWriter(out, format);
		  output.write(doc);
		  String result = out.toString();
		  System.out.println(result);
	}
	
	/**
	 * 获取简单配置的信息的子节点信息集
	 * <root-name>
	 *   <nodeName>
	 *      <属性>值</属性>
	 *   </nodeName> 
	 * </root-name>
	 * @param in
	 * @param nodeName
	 * @return
	 * @throws Exception
	 */
	public static List<Properties> getSimpleNodeValues(InputStream in,String nodeName)throws Exception{
		Element root = getRootElement(in);
		List<Node> nodes = nodeList(root,nodeName);
		List<Properties> nodeValues = null;
		if(nodes != null && nodes.size() > 0){
			nodeValues = new ArrayList<Properties>();
		    for(Node node:nodes){
		    	Properties pro = getChildValues(node);
		    	nodeValues.add(pro);
		    }
		}
		
		return nodeValues;
	}
	
	/**
	 * 直接将简单配置配置转换成对象的队列,格式如下
	 * <root-name>
	 *   <nodeName>
	 *      <属性>值</属性>
	 *   </nodeName> 
	 * </root-name>
	 * @param in
	 * @param nodeName
	 * @param className
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static List getSimeleNodeObject(InputStream in,String nodeName,String className)throws Exception{
		Element root = getRootElement(in);
		List<Node> nodes = nodeList(root,nodeName);
		List<Object> nodeValues = null;
		if(nodes != null && nodes.size() > 0){
			nodeValues = new ArrayList<Object>();
			 for(Node node:nodes){
			    	Properties pro = getChildValues(node);
			    	if(pro != null){
			    	   Object temp = ObjectHelper.simpleNewInstance(className);
			    	   Iterator it = pro.keySet().iterator();
			    	   while(it.hasNext()){
			    		   String key = (String)it.next();
			    		   OgnlHelper.setValue(temp, key.trim(), ((String)pro.get(key)).trim());
			    	   }
			    	   nodeValues.add(temp);
			    	}
			    }
		}
		return nodeValues;
	}
	
	
	/**
	 * 获取简单配置的信息的子节点信息集
	 * <root-name>
	 *   <nodeName>
	 *      <属性>值</属性>
	 *   </nodeName> 
	 * </root-name>
	 * @param in
	 * @param nodeName
	 * @return
	 * @throws Exception
	 */
	public static List<Properties> getSimpleNodeValues(String filePath,int filePathType,String nodeName)throws Exception{
		InputStream in = null;
		 List<Properties> nodeValues = null;
		try
		{
			in = FileLoader.getInputStream(filePath,filePathType);
	    	Element root = getRootElement(in);
		    List<Node> nodes = nodeList(root,nodeName);
		   
	 	    if(nodes != null && nodes.size() > 0){
			   nodeValues = new ArrayList<Properties>();
		       for(Node node:nodes){
		    	  Properties pro = getChildValues(node);
		    	  nodeValues.add(pro);
		       }
		     }
		}finally{
			if(in != null)
				try{in.close();}catch(Exception e){}
		}
		return nodeValues;
	}
}
